﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.EntityClient;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.Unity;
using Defero.Core;

namespace Defero.Infrastucture.Repositories
{
    public abstract class Repository<TContext> : IRepository where TContext : ObjectContext, new()
    {
        /// <summary>
        /// Contenedor de unidades de trabajo;
        /// </summary>
        UnityContainer UnitOfWorkContainer;
        /// <summary>
        /// Base de datos.
        /// </summary>
        Database CommandDatabase;
        /// <summary>
        /// Constructor deafult.
        /// </summary>
        /// <param name="name">Nombre del repositorio.</param>
        public Repository(DbConnection connection)
        {
            UnitOfWorkContainer = new UnityContainer();
            Context = (TContext)Activator.CreateInstance(typeof(TContext), connection);
            CommandDatabase = DatabaseFactory.CreateDatabase("CommandDatabase");
        }
        /// <summary>
        /// Contexto de datos.
        /// </summary>
        public TContext Context { get; private set; }
        /// <summary>
        /// Obtiene una instancia de UnitOfWork aplicando Singleton
        /// </summary>
        /// <typeparam name="T">Tipo de entidad de la unidad</typeparam>
        /// <param name="repository">Repositorio padre.</param>
        protected UnitOfWork<TEntity, TContext> Resolve<TEntity>() where TEntity : EntityObject
        {
            if (!UnitOfWorkContainer.IsRegistered<TEntity>())
                UnitOfWorkContainer.RegisterType<TEntity>(new ContainerControlledLifetimeManager());

            return UnitOfWorkContainer.Resolve<UnitOfWork<TEntity, TContext>>(new DependencyOverride<Repository<TContext>>(this));
        }
    }
}
